#include "stdafx.h"
#include "Netbase.h"

static xgc_uint16	header_space( xgc_lpvoid context )
{
	return 4;
}

static xgc_uint32	packet_length( const xgc_byte* header )
{
	return *(xgc_uint16*)header;
}

static xgc_uint32	packet_filter( const xgc_byte* header )	// filter your interesting packet, return event code
{
	if( header[2] == SYSTEM_MESSAGE_TYPE )
	{
		switch( header[3] )
		{
		case EVENT_PING:
			return FILTER_SYSTEM_PING;
			break;
		case EVENT_PONG:
			return FILTER_SYSTEM_PONG;
			break;
		}
	}
	return FILTER_PASS;
}

static xgc_uint32	packet_system( xgc_byte event, xgc_byte* header )		// return packet base address;
{
	// event = EVENT_CODE { EVENT_ACCEPT, EVENT_CLOSE, EVENT_ERROR, EVENT_CONNECT, EVENT_PING, EVENT_PONG }
	switch( event )
	{
	case EVENT_ACCEPT:
	case EVENT_CLOSE:
	case EVENT_CONNECT:
	case EVENT_ERROR:
	case EVENT_PING:
	case EVENT_PONG:
		header[2] = SYSTEM_MESSAGE_TYPE;
		header[3] = event;
		break;
	}

	return 4;
}

static xgc_uint32	packet_finial( xgc_byte* header, xgc_uint32 length )
{
	*(xgc_uint16*)header = (xgc_uint16)length;
	return length;
}

static xgc_bool	packet_verifiy( const xgc_byte* header, xgc_uint32 size, xgc_lpvoid context)
{
	return true;
}

static xgc_uint32 packet_decrypt( const xgc_byte* header, xgc_uint32 size, xgc_byte* output, xgc_lpvoid context)
{
	for( xgc_size i = 0; output && i < size; ++i, ++header, ++output )
	{
		*output = *header ^ 0xf0;
	}
	return size;
}

static xgc_uint32 packet_encrypt( const xgc_byte* header, xgc_uint32 size, xgc_byte* output, xgc_lpvoid context)
{
	for( xgc_size i = 0; output && i < size; ++i, ++header, ++output )
	{
		*output = *header ^ 0xf0;
	}
	return size;
}

net::PacketProtocal ProtocalCustom = 
{
	header_space,
	packet_length,
	packet_filter,
	packet_system,
	packet_finial,
	packet_verifiy,
	packet_decrypt,
	packet_encrypt,
};
